home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / misc / pchglib12.lha / SHAM2PCHG.c < prev    next >
C/C++ Source or Header  |  1992-11-15  |  4KB  |  119 lines

  1. #include <proto/exec.h>
  2. #include <proto/graphics.h>
  3. #include <exec/types.h>
  4. #include <exec/memory.h>
  5. #include <hardware/custom.h>
  6. #include <graphics/gfxmacros.h>
  7. #include <graphics/copper.h>
  8. #include <intuition/screens.h>
  9. #include <iff/pchg.h>
  10. #include <clib/pchglib_protos.h>
  11.  
  12. #if INCLUDE_VERSION<36
  13. FAILURE!! Amiga includes version<36
  14. #endif
  15.  
  16. /****** pchg.lib/PCHG_SHAM2PCHG ****************************************
  17.  
  18.    NAME
  19.        PCHG_SHAM2PCHG -- Fakes a PCHG chunk from a SHAM chunk
  20.  
  21.    SYNOPSIS
  22.        PCHGHeader = PCHG_SHAM2PCHG(SHAMChunk, SHAMSize, Increment);
  23.  
  24.        struct PCHGHeader *PCHG_SHAM2PCHG(UWORD *, ULONG, WORD);
  25.  
  26.    FUNCTION
  27.        Creates a PCHGHeader and a LINEMASK (see the PCHG specs) by parsing a
  28.        SHAM chunk. The memory block containing the SHAM is overwritten by an
  29.        array of SmallPaletteChanges (this array is always shorter than the
  30.        original SHAM chunk). A memory block is allocated for the PCHGHeader
  31.        and for the LINEMASK (which is of course placed just after the
  32.        PCHGHeader), and is returned by the function. You can then free it
  33.        using as dimension the size of a PCHGHeader plus the number of bytes
  34.        required by the longword mask, i.e.,
  35.  
  36.             sizeof(struct PCHGHeader)+((PCHGHeader->LineCount+31)/32)*4
  37.  
  38.        You can parse this chunk as any PCHG chunk, but the changes per line
  39.        could be more than seven (up to fifteen). This function, however, is
  40.        intelligent, and doesn't generate useless color changes (i.e., it
  41.        never pokes again the same value two times). You will usually call
  42.  
  43.        PCHG_SetUserCopList(0, 0, Screen, PCHGHeader, &PCHGHeader[1], SHAMChunk);
  44.  
  45.        after using PCHG_SHAM2PCHG().
  46.  
  47.  
  48.    INPUTS
  49.        SHAMChunk    - The address of the SHAM chunk.
  50.        SHAMSize     - The size of the SHAM chunk (we handle >200
  51.                       lines chunks).
  52.        Increment    - The increment to add to the line number while parsing
  53.                       the SHAM chunk. It has to be 1 for non-laced pictures,
  54.                       2 for laced pictures.
  55.  
  56.    RESULT
  57.        PCHGHeader   - A pointer to a memory block contaning a PCHGHeader
  58.                       followed by a LINEMASK, or NULL if the memory
  59.                       allocation failed. You have to free this memory after
  60.                       you used it.
  61.  
  62.    EXAMPLE
  63.  
  64.    NOTES
  65.        This function will not generate any change on line 0, because the
  66.        line 0 colors should be the same of the CMAP. If you get any problem,
  67.        you can feed the first line of the SHAM chunk as a color table to the
  68.        screen before calling this function.
  69.  
  70.        Since this function writes in the fake PCHG chunk only the real
  71.        changes, you will generally get a better display using this function
  72.        and PCHG_SetUserCopList() than with SHAMVIEW, for instance.
  73.  
  74.    BUGS
  75.  
  76.    SEE ALSO
  77.  
  78. *****************************************************************************/
  79.  
  80. struct PCHGHeader *PCHG_SHAM2PCHG(UWORD *SHAMChunk, ULONG SHAMSize, WORD Increment) {
  81.  
  82.     int i,j,k;
  83.     UWORD Pal[16], *p;
  84.     struct PCHGHeader *pch;
  85.     ULONG *LineMask, LineCount;
  86.  
  87.     LineCount = (SHAMSize-2)/32;
  88.  
  89.     if (!(pch = AllocMem(sizeof(struct PCHGHeader)+((LineCount*Increment+31)/32)*4, MEMF_PUBLIC | MEMF_CLEAR))) return(NULL);
  90.     LineMask = (void *)&pch[1];
  91.  
  92.     for(i=1; i<16; i++) Pal[i] = SHAMChunk[i+1] & 0xFFF;
  93.     p = SHAMChunk++;
  94.     pch->MinReg = 15;
  95.  
  96.     for(i=1; i<LineCount; i++) {
  97.         for(j=1, k=0; j<16; j++)
  98.             if (Pal[j] != SHAMChunk[i*16+j] & 0xFFF) {
  99.                 p[++k] = (Pal[j] = SHAMChunk[i*16+j] & 0xFFF) | j<<12;
  100.                 if (pch->MinReg>j) pch->MinReg = j;
  101.                 if (pch->MaxReg<j) pch->MaxReg = j;
  102.             }
  103.         if (k) {
  104.             *p = k<<8;
  105.             p+=(k+1);
  106.             LineMask[(i*Increment)/32] |= 1<<(31-(i*Increment)%32);
  107.             pch->ChangedLines++;
  108.             pch->TotalChanges += k;
  109.             if (k>pch->MaxChanges) pch->MaxChanges = k;
  110.         }
  111.     }
  112.  
  113.     pch->Compression = PCHG_COMP_NONE;
  114.     pch->Flags = PCHGF_12BIT;
  115.     pch->StartLine = 0;
  116.     pch->LineCount = LineCount*Increment;
  117.     return(pch);
  118. }
  119.